package com.pony.iphone.data;

import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author pony
 * @version 1.0
 * @description: 文件持久化 类
 * @create 2025/8/12 22:05
 */
@Data
@Component
//@NoArgsConstructor
//@AllArgsConstructor
public class FileDB {
    // Jar 包的相对路径
    private String relativeFilePath = "data/count.txt";
    // Jar 所在目录，绝对路径
    private Path absoluteFilePath;

    @PostConstruct
    public void init() {
        initAbsolutePath();
    }

    public void setRelativeFilePath(String relativeFilePath) {
        this.relativeFilePath = relativeFilePath;
        initAbsolutePath(); // 重新计算绝对路径
    }

    // 获取当前jar包所在目录，绝对路径
    public void initAbsolutePath() {
        try {
            String jarDir = getApplicationDirectory();
            this.absoluteFilePath = Paths.get(jarDir, relativeFilePath);

            // 确保目录存在
            if (!Files.exists(absoluteFilePath.getParent())) {
                Files.createDirectories(absoluteFilePath.getParent());
            }
        } catch (Exception e) {
            throw new RuntimeException("无法确定文件路径: " + e.getMessage(), e);
        }
    }

    /**
     * 获取应用运行目录
     * @return 应用运行目录路径
     */
    private String getApplicationDirectory() {
        try {
            // 方法1: 尝试获取jar包所在目录
            File jarFile = new File(getClass().getProtectionDomain()
                    .getCodeSource().getLocation().toURI());

            if (jarFile.isFile()) {
                // 在jar包中运行
                return jarFile.getParentFile().getPath();
            } else {
                // 在IDE中运行或者以其他方式运行
                return System.getProperty("user.dir");
            }
        } catch (Exception e) {
            // 方法2: 使用备用方法获取路径
            try {
                String path = new File("").getAbsolutePath();
                return path;
            } catch (Exception ex) {
                // 方法3: 使用系统属性
                String userDir = System.getProperty("user.dir");
                if (userDir != null) {
                    return userDir;
                }
                throw new RuntimeException("无法获取应用目录", ex);
            }
        }
    }

    /**
     * 读取文件中的数字，如果文件不存在则创建并返回0
     * @return 文件中的数字，如果文件不存在或内容不是数字则返回0
     */
    public int readNumber() {
        try {
            if (!Files.exists(absoluteFilePath)) {
                Files.createDirectories(absoluteFilePath.getParent());
                Files.write(absoluteFilePath, "0".getBytes());
                return 0;
            }

            String content = new String(Files.readAllBytes(absoluteFilePath));
            return Integer.parseInt(content.trim());
        } catch (NumberFormatException e) {
            return 0;
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败", e);
        }
    }

    /**
     * 将数字写入文件（覆盖写入）
     * @param number 要写入的数字
     */
    public void writeNumber(int number) {
        try {
            Files.write(absoluteFilePath, String.valueOf(number).getBytes());
        } catch (IOException e) {
            throw new RuntimeException("写入文件失败", e);
        }
    }

    /**
     * 读取当前数字，加1后写入文件
     * @return 加1后的新数字
     */
    public int incrementAndGet() {
        int currentValue = readNumber();
        int newValue = currentValue + 1;
        writeNumber(newValue);
        return newValue;
    }
}
